package com.duobaoyu.dby.supply.biz.strategy.message.order.change;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.duobaoyu.dby.channel.adapter.bean.message.order.OrderMessage;
import com.duobaoyu.dby.channel.adapter.enums.BizMessageTypeEnum;
import com.duobaoyu.dby.channel.adapter.enums.ChannelCodeEnum;
import com.duobaoyu.dby.channel.adapter.enums.biz.order.OrderStatusEnum;
import com.duobaoyu.dby.channel.common.util.DingDingExtUtils;
import com.duobaoyu.dby.supply.biz.constant.OperateSourceConstants;
import com.duobaoyu.dby.supply.biz.producer.SupplyChainMQProducer;
import com.duobaoyu.dby.supply.biz.service.order.OrderService;
import com.duobaoyu.dby.supply.biz.strategy.message.order.base.BaseOrderAsyncHandler;
import com.duobaoyu.dby.supply.common.biz.bo.message.ChannelMessageBO;
import com.duobaoyu.dby.supply.common.biz.bo.order.ChannelOrderDetailOutBO;
import com.duobaoyu.dby.supply.db.entity.order.Order;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单状态变更
 *
 * @author fengshaoyu
 * @version 1.0.0
 * @date 2023/10/21 10:43
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderStateChangeAsyncHandler extends BaseOrderAsyncHandler {

    private final OrderService orderService;
    private final TransactionTemplate transactionTemplate;
    private final SupplyChainMQProducer supplyChainMQProducer;

    @Override
    protected Set<String> channelCodes() {
        return Sets.newHashSet(ChannelCodeEnum.ALIBABA_DISTRIBUTION.getValue(),
                ChannelCodeEnum.LINKED_MALL.getValue(),
                ChannelCodeEnum.ZKH.getValue(),
                ChannelCodeEnum.DE_LI.getValue(),
                ChannelCodeEnum.ORDERING.getValue(),
                ChannelCodeEnum.FU_LU.getValue(),
                ChannelCodeEnum.ORANGE_COUPON.getValue(),
                ChannelCodeEnum.CHENG_YANG.getValue(),
                ChannelCodeEnum.JD_VOP.getValue(),
                ChannelCodeEnum.ONE_WALLET.getValue(),
                ChannelCodeEnum.ORIGINAL_LIFE.getValue(),
                ChannelCodeEnum.BLUE_BROTHER.getValue(),
                ChannelCodeEnum.NIAN_NIAN_KA.getValue(),
                ChannelCodeEnum.SIMPLE_LIFE.getValue(),
                ChannelCodeEnum.XIN_LIAN_V2.getValue(),
                ChannelCodeEnum.XING_YUN.getValue());
    }

    @Override
    protected Set<Integer> bizMessageTypes() {
        return Sets.newHashSet(BizMessageTypeEnum.ORDER_STATUS_CHANGE.getValue());
    }

    @Override
    protected Boolean executeHandler(ChannelMessageBO channelMessage, Object beforeResult) {
        List<OrderMessage> orderMessages = getMessage(channelMessage);
        List<Order> orderList = getOrderList(channelMessage);

        if (CollectionUtils.isEmpty(orderList)) {
            return Boolean.FALSE;
        }

        for (OrderMessage orderMessage : orderMessages) {
            try {
            	List<Order> orders = new ArrayList<>();
                transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(@NotNull TransactionStatus transactionStatus) {
                        for (Order order : orderList) {
                            Boolean orderSnCheck = StringUtils.isNotBlank(orderMessage.getOrderTradeSn()) ? Objects.equals(orderMessage.getOrderTradeSn(), order.getOrderTradeSn()) : Boolean.TRUE;
                            Boolean channelOrderSnCheck = StringUtils.isNotBlank(orderMessage.getChannelOrderSn()) ? Objects.equals(orderMessage.getChannelOrderSn(), order.getChannelOrderSn()) : Boolean.TRUE;
                            Boolean channelOrderParentSnCheck = StringUtils.isNotBlank(orderMessage.getChannelOrderParentSn()) ? Objects.equals(orderMessage.getChannelOrderParentSn(), order.getChannelOrderParentSn()) : Boolean.TRUE;
                            Boolean channelTradeOrderSnCheck = StringUtils.isNotBlank(orderMessage.getChannelTradeOrderSn()) ? Objects.equals(orderMessage.getChannelTradeOrderSn(), order.getChannelTradeOrderSn()) : Boolean.TRUE;

                            if (orderSnCheck && channelOrderSnCheck && channelOrderParentSnCheck && channelTradeOrderSnCheck) {
                                OrderStatusEnum orderSubStatusOld = OrderStatusEnum.getOrderSubStatusEnum(order.getOrderStatus());
                                OrderStatusEnum orderSubStatusNew = OrderStatusEnum.getOrderSubStatusEnum(orderMessage.getOrderStatus());
                                if (orderSubStatusOld == orderSubStatusNew) {
                                    log.info("状态一致,不做处理: orderSn={}", order.getOrderSn());
                                    continue;
                                }
                                orderService.updateStatusByOrderSnList(Collections.singletonList(order.getOrderSn()), orderSubStatusNew, orderSubStatusOld, OperateSourceConstants.OPERATION_CHANNEL, Optional.ofNullable(BizMessageTypeEnum.bizMessageTypeEnum(channelMessage.getMessageType())).map(BizMessageTypeEnum::getDescribe).orElse("渠道消息"), null);

                                //同步虚拟订单数据
                                ChannelOrderDetailOutBO channelOrderDetail = getChannelOrderDetailOut(order);
                                syncOrderProduct(order, channelOrderDetail);
								orders.add(order);
                            }
                        }
                    }
                });
				orders.stream().collect(Collectors.toMap(Order::getSupplyTradeSn,Order::getServerName, (v1, v2) -> v2)).forEach(supplyChainMQProducer::orderAlterSend);
            } catch (Exception e) {
                log.warn("同步订单状态异常: orderMessage={}",orderMessage, e);
                DingDingExtUtils.sendMarkdownMsg(String.format("渠道=%s,供应链三方交易单号=%s", orderMessage.getChannelCode(), orderMessage.getOrderTradeSn()), "同步订单状态异常");
            }
        }
        return Boolean.TRUE;
    }

}
